﻿using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;

namespace UltimateNavigationFramework.Commands
{
    /// <summary>
    /// Provides behavior for any clickable control and will execute a command when the control is double clicked.
    /// Does not disable the control if the command cannot be executed.
    /// </summary>
    public class DoubleClickCommandBehavior : NavigateCommandBehaviorBase
    {
        #region Constants and Fields
        private readonly DispatcherTimer _doubleClickTimer;
        #endregion

        #region Constructors and Destructors
        /// <summary>
        /// Initializes a new instance of the DoubleClickCommandBehavior class.
        /// </summary>
        public DoubleClickCommandBehavior(UIElement obj)
            : base(obj)
        {
            if (obj == null)
                throw new System.ArgumentNullException("obj");

            // Default double-click interval is 250 milliseconds.
            _doubleClickTimer = new DispatcherTimer
            {
                Interval = new TimeSpan(0, 0, 0, 0, 250)
            };

            _doubleClickTimer.Tick += (sender, o) => _doubleClickTimer.Stop();
        }

        #endregion

        /// <summary>
        /// Subscribes to the MouseLeftButtonUp of the data grid and times the intervals between the events,
        /// if the time between clicks is less than the configured interval the command is executed.
        /// </summary>
        /// <remarks>Originally attached to MouseLeftButtonDown but the events were not firing.</remarks>
        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.AddHandler(UIElement.MouseLeftButtonDownEvent,
                                                   new MouseButtonEventHandler(OnMouseAction), true);
        }

        /// <summary>
        /// Disposes of the observable
        /// </summary>
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.RemoveHandler(UIElement.MouseLeftButtonDownEvent,
                                           new MouseButtonEventHandler(OnMouseAction));
            if (_doubleClickTimer.IsEnabled)
            {
                _doubleClickTimer.Stop();
            }            
        }

        private void OnMouseAction(object sender, MouseButtonEventArgs e)
        {
            if (!_doubleClickTimer.IsEnabled)
            {
                _doubleClickTimer.Start();
                return;
            }
            _doubleClickTimer.Stop();
            this.UpdateEnabledState();
            this.ExecuteCommand();
        }
    }
}
